Acceleration Plot
computeThreshold <- function(x, xmin=min(x), xmax=max(x)) {
x <- x[x >= xmin & x <= xmax]
xArr <- matrix(x, nrow = 1, ncol = length(x))
threshold <- otsu(xArr, range=c(xmin, xmax))
return(threshold)
}
computeThresholdForAcceleration <- function(acc){
return(computeThreshold(acc, xmin=0, xmax=20))
}
findModes <- function(x) {
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
acc_thresholds <- vector(mode="list", length=length(persons))
names(acc_thresholds) <- persons
acc_sd_thresholds <- vector(mode="list", length=length(persons))
names(acc_sd_thresholds) <- persons
speed_sd_thresholds <- vector(mode="list", length=length(persons))
names(speed_sd_thresholds) <- persons
for (p in persons) {
pData <- all_Drive2[(all_Drive2$Subject==as.integer(p) | all_Drive2$Subject==p),]
acc_th <- computeThresholdForAcceleration(pData$Acceleration)
acc_th_sd <- computeThresholdForAcceleration(pData$Acc_std)
speed_th_sd <- computeThresholdForAcceleration(pData$Speed_std)
acc_thresholds[[p]] <- as.numeric(acc_th)
acc_sd_thresholds[[p]] <- as.numeric(acc_th_sd)
speed_sd_thresholds[[p]] <- as.numeric(speed_th_sd)
acc_pl <- ggplot(pData, aes(x=Acceleration)) + geom_density() + geom_vline(aes(xintercept=acc_th), color="blue", linetype="dashed", size=1)
acc_sd_pl <- ggplot(pData, aes(x=Acc_std)) + geom_density() + geom_vline(aes(xintercept=acc_th_sd), color="red", linetype="dashed", size=1)
speed_sd_pl <- ggplot(pData, aes(x=Speed_std)) + geom_density() + geom_vline(aes(xintercept=speed_th_sd), color="red", linetype="dashed", size=1)
plot(speed_sd_pl)
print(paste0(p, " - Threshold (Acc) =", acc_th, " & (Acc SD) =", acc_th_sd, " & (Speed SD) =", acc_th_sd))
}
[1] "01 - Threshold (Acc) =8.2421875 & (Acc SD) =5.546875 & (Speed SD) =5.546875"
[1] "02 - Threshold (Acc) =9.9609375 & (Acc SD) =5.8203125 & (Speed SD) =5.8203125"
[1] "03 - Threshold (Acc) =9.1796875 & (Acc SD) =7.0703125 & (Speed SD) =7.0703125"
[1] "04 - Threshold (Acc) =10.1953125 & (Acc SD) =6.40625 & (Speed SD) =6.40625"
[1] "05 - Threshold (Acc) =9.9609375 & (Acc SD) =4.8046875 & (Speed SD) =4.8046875"
[1] "06 - Threshold (Acc) =10.234375 & (Acc SD) =6.4453125 & (Speed SD) =6.4453125"
[1] "07 - Threshold (Acc) =11.6015625 & (Acc SD) =7.3828125 & (Speed SD) =7.3828125"
[1] "09 - Threshold (Acc) =9.296875 & (Acc SD) =6.0546875 & (Speed SD) =6.0546875"
[1] "12 - Threshold (Acc) =9.7265625 & (Acc SD) =7.0703125 & (Speed SD) =7.0703125"
[1] "13 - Threshold (Acc) =10.5859375 & (Acc SD) =7.6171875 & (Speed SD) =7.6171875"
[1] "15 - Threshold (Acc) =9.1796875 & (Acc SD) =6.6796875 & (Speed SD) =6.6796875"
[1] "16 - Threshold (Acc) =9.5703125 & (Acc SD) =8.7109375 & (Speed SD) =8.7109375"
[1] "17 - Threshold (Acc) =9.1796875 & (Acc SD) =6.8359375 & (Speed SD) =6.8359375"
[1] "18 - Threshold (Acc) =10.9375 & (Acc SD) =6.5234375 & (Speed SD) =6.5234375"
[1] "22 - Threshold (Acc) =9.8046875 & (Acc SD) =5.6640625 & (Speed SD) =5.6640625"
[1] "24 - Threshold (Acc) =9.0234375 & (Acc SD) =7.2265625 & (Speed SD) =7.2265625"
[1] "29 - Threshold (Acc) =6.71875 & (Acc SD) =6.2109375 & (Speed SD) =6.2109375"
[1] "30 - Threshold (Acc) =8.90625 & (Acc SD) =6.5234375 & (Speed SD) =6.5234375"
[1] "31 - Threshold (Acc) =11.875 & (Acc SD) =6.2109375 & (Speed SD) =6.2109375"
[1] "32 - Threshold (Acc) =5.3515625 & (Acc SD) =7.1484375 & (Speed SD) =7.1484375"
[1] "41 - Threshold (Acc) =12.2265625 & (Acc SD) =5.8203125 & (Speed SD) =5.8203125"





















mean_pp <- vector(mode="list", length=length(persons))
names(mean_pp) <- persons
std_pp <- vector(mode="list", length=length(persons))
names(std_pp) <- persons
# Mean (Turning)
mean_pp_seg0 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0) <- persons
mean_pp_seg0_1 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_1) <- persons
mean_pp_seg0_2 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_2) <- persons
mean_pp_seg0_3 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_3) <- persons
mean_pp_seg0_4 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_4) <- persons
# Mean (Straight)
mean_pp_seg1 <- vector(mode="list", length=length(persons))
names(mean_pp_seg1) <- persons
mean_pp_seg2 <- vector(mode="list", length=length(persons))
names(mean_pp_seg2) <- persons
mean_pp_seg3 <- vector(mode="list", length=length(persons))
names(mean_pp_seg3) <- persons
mean_pp_seg4 <- vector(mode="list", length=length(persons))
names(mean_pp_seg4) <- persons
mean_pp_max <- vector(mode="list", length=length(persons))
names(mean_pp_max) <- persons
# SD (Turning)
std_pp_seg0 <- vector(mode="list", length=length(persons))
names(std_pp_seg0) <- persons
std_pp_seg0_1 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_1) <- persons
std_pp_seg0_2 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_2) <- persons
std_pp_seg0_3 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_3) <- persons
std_pp_seg0_4 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_4) <- persons
# SD (Straight)
std_pp_seg1 <- vector(mode="list", length=length(persons))
names(std_pp_seg1) <- persons
std_pp_seg2 <- vector(mode="list", length=length(persons))
names(std_pp_seg2) <- persons
std_pp_seg3 <- vector(mode="list", length=length(persons))
names(std_pp_seg3) <- persons
std_pp_seg4 <- vector(mode="list", length=length(persons))
names(std_pp_seg4) <- persons
std_pp_max <- vector(mode="list", length=length(persons))
names(std_pp_max) <- persons
# Acceleration Partitioning
mean_pp_HighAcc <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc) <- persons
mean_pp_LowAcc <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc) <- persons
std_pp_HighAcc <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc) <- persons
std_pp_LowAcc <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc) <- persons
# Accel + Segmentation
mean_pp_HighAcc1 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc1) <- persons
mean_pp_LowAcc1 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc1) <- persons
std_pp_HighAcc1 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc1) <- persons
std_pp_LowAcc1 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc1) <- persons
mean_pp_HighAcc2 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc2) <- persons
mean_pp_LowAcc2 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc2) <- persons
std_pp_HighAcc2 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc2) <- persons
std_pp_LowAcc2 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc2) <- persons
mean_pp_HighAcc3 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc3) <- persons
mean_pp_LowAcc3 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc3) <- persons
std_pp_HighAcc3 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc3) <- persons
std_pp_LowAcc3 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc3) <- persons
mean_pp_HighAcc4 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc4) <- persons
mean_pp_LowAcc4 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc4) <- persons
std_pp_HighAcc4 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc4) <- persons
std_pp_LowAcc4 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc4) <- persons
for(p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
pData_act3 <- pData[pData$Activity==3,]
# Data Partitioning
pData_seg0 <- pData[pData$Phase==0,]
pData_seg0_1 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 100 & pData$Time < 200,]
pData_seg0_2 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 200 & pData$Time < 300,]
pData_seg0_3 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 300 & pData$Time < 400,]
pData_seg0_4 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 400 & pData$Time < 500,]
pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
# pData_HighAcc <- pData[pData$Acceleration >= acc_thresholds[[p]],]
# pData_LowAcc <- pData[pData$Acceleration < acc_thresholds[[p]],]
pData_HighAcc <- pData[pData$Acc_std >= acc_sd_thresholds[[p]] | pData$Speed_std >= speed_sd_thresholds[[p]],]
pData_LowAcc <- pData[pData$Acc_std < acc_sd_thresholds[[p]] & pData$Speed_std < speed_sd_thresholds[[p]],]
pData_HighAcc1 <- pData_HighAcc[(pData_HighAcc$Distance < 350),]
pData_LowAcc1 <- pData_LowAcc[(pData_LowAcc$Distance < 350),]
pData_HighAcc2 <- pData_HighAcc[(pData_HighAcc$Distance >= 350 & pData_HighAcc$Distance < 700),]
pData_LowAcc2 <- pData_LowAcc[(pData_LowAcc$Distance >= 350 & pData_LowAcc$Distance < 700),]
pData_HighAcc3 <- pData_HighAcc[(pData_HighAcc$Distance >= 700 & pData_HighAcc$Distance < 1050),]
pData_LowAcc3 <- pData_LowAcc[(pData_LowAcc$Distance >= 700 & pData_LowAcc$Distance < 1050),]
pData_HighAcc4 <- pData_HighAcc[(pData_HighAcc$Distance >= 1050),]
pData_LowAcc4 <- pData_LowAcc[(pData_LowAcc$Distance >= 1050),]
mean_pp[[p]] <- mean(pData_act3$ppLogNormalized)
std_pp[[p]] <- sd(pData$ppLogNormalized)
mean_pp_seg0[[p]] <- mean(pData_seg0$ppLogNormalized)
mean_pp_seg0_1[[p]] <- mean(pData_seg0_1$ppLogNormalized)
mean_pp_seg0_2[[p]] <- mean(pData_seg0_2$ppLogNormalized)
mean_pp_seg0_3[[p]] <- mean(pData_seg0_3$ppLogNormalized)
mean_pp_seg0_4[[p]] <- mean(pData_seg0_4$ppLogNormalized)
mean_pp_seg1[[p]] <- mean(pData_seg1$ppLogNormalized)
mean_pp_seg2[[p]] <- mean(pData_seg2$ppLogNormalized)
mean_pp_seg3[[p]] <- mean(pData_seg3$ppLogNormalized)
mean_pp_seg4[[p]] <- mean(pData_seg4$ppLogNormalized)
mean_pp_max[[p]] <- max(mean_pp_seg1[[p]], mean_pp_seg2[[p]], mean_pp_seg3[[p]], mean_pp_seg4[[p]])
std_pp_seg0[[p]] <- sd(pData_seg0$ppLogNormalized)
std_pp_seg0_1[[p]] <- sd(pData_seg0_1$ppLogNormalized)
std_pp_seg0_2[[p]] <- sd(pData_seg0_2$ppLogNormalized)
std_pp_seg0_3[[p]] <- sd(pData_seg0_3$ppLogNormalized)
std_pp_seg0_4[[p]] <- sd(pData_seg0_4$ppLogNormalized)
std_pp_seg1[[p]] <- sd(pData_seg1$ppLogNormalized)
std_pp_seg2[[p]] <- sd(pData_seg2$ppLogNormalized)
std_pp_seg3[[p]] <- sd(pData_seg3$ppLogNormalized)
std_pp_seg4[[p]] <- sd(pData_seg4$ppLogNormalized)
std_pp_max[[p]] <- max(std_pp_seg1[[p]], std_pp_seg2[[p]], std_pp_seg3[[p]], std_pp_seg4[[p]])
# Acceleration
mean_pp_HighAcc[[p]] <- mean(pData_HighAcc$ppNext)
mean_pp_LowAcc[[p]] <- mean(pData_LowAcc$ppNext)
std_pp_HighAcc[[p]] <- sd(pData_HighAcc$ppNext)
std_pp_LowAcc[[p]] <- sd(pData_LowAcc$ppNext)
mean_pp_HighAcc1[[p]] <- mean(pData_HighAcc1$ppNext)
mean_pp_LowAcc1[[p]] <- mean(pData_LowAcc1$ppNext)
std_pp_HighAcc1[[p]] <- sd(pData_HighAcc1$ppNext)
std_pp_LowAcc1[[p]] <- sd(pData_LowAcc1$ppNext)
mean_pp_HighAcc2[[p]] <- mean(pData_HighAcc2$ppNext)
mean_pp_LowAcc2[[p]] <- mean(pData_LowAcc2$ppNext)
std_pp_HighAcc2[[p]] <- sd(pData_HighAcc2$ppNext)
std_pp_LowAcc2[[p]] <- sd(pData_LowAcc2$ppNext)
mean_pp_HighAcc3[[p]] <- mean(pData_HighAcc3$ppNext)
mean_pp_LowAcc3[[p]] <- mean(pData_LowAcc3$ppNext)
std_pp_HighAcc3[[p]] <- sd(pData_HighAcc3$ppNext)
std_pp_LowAcc3[[p]] <- sd(pData_LowAcc3$ppNext)
mean_pp_HighAcc4[[p]] <- mean(pData_HighAcc4$ppNext)
mean_pp_LowAcc4[[p]] <- mean(pData_LowAcc4$ppNext)
std_pp_HighAcc4[[p]] <- sd(pData_HighAcc4$ppNext)
std_pp_LowAcc4[[p]] <- sd(pData_LowAcc4$ppNext)
}
plt_AllAcc <- vector(mode="list", length=length(persons))
names(plt_AllAcc) <- persons
COLOR_ACC = "#02A3C8"
COLOR_PP = "#F28E8E"
COLOR_BRAKE = "#888888"
y1 <- list(
tickfont = list(color = COLOR_ACC),
title="Degree",
range=c(0, max(all_Drive3$Acceleration))
)
y2 <- list(
tickfont = list(color = COLOR_PP),
overlaying = "y",
side = "right",
title = "Log Perspiration",
showgrid = FALSE,
range=c(-0.6, 0.9)
# range=c(min(all_Drive3$ppLogNormalized), max(all_Drive3$ppLogNormalized))
)
for (p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
pData_seg0 <- pData[pData$Phase==0,]
pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
plot_Acc <- plot_ly(pData, x = ~Time, height=400, width=900) %>%
# add_trace(name="Acceleration", y = ~Acceleration, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_ACC)) %>%
add_trace(name="PP", y = ~ppLogNormalized, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_PP), yaxis = "y2") %>%
add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp[[p]], yend = mean_pp[[p]],
yaxis = "y2", name="Avg. PP (straight)",
line=list(color="darkgray", dash = 'dot')) %>%
add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp_seg0[[p]], yend = mean_pp_seg0[[p]],
yaxis = "y2", name="Avg. PP (turning)",
line=list(color="black", dash = 'dot')) %>%
add_segments(x = min(pData_seg1$Time), xend = max(pData_seg1$Time), y = mean_pp_seg1[[p]], yend = mean_pp_seg1[[p]],
yaxis = "y2", name="Avg. PP (1st part)",
line=list(color="red", dash = 'dot')) %>%
add_segments(x = min(pData_seg2$Time), xend = max(pData_seg2$Time), y = mean_pp_seg2[[p]], yend = mean_pp_seg2[[p]],
yaxis = "y2", name="Avg. PP (2nd part)",
line=list(color="green", dash = 'dot')) %>%
add_segments(x = min(pData_seg3$Time), xend = max(pData_seg3$Time), y = mean_pp_seg3[[p]], yend = mean_pp_seg3[[p]],
yaxis = "y2", name="Avg. PP (3rd part)",
line=list(color="blue", dash = 'dot')) %>%
add_segments(x = min(pData_seg4$Time), xend = max(pData_seg4$Time), y = mean_pp_seg4[[p]], yend = mean_pp_seg4[[p]],
yaxis = "y2", name="Avg. PP (4th part)",
line=list(color="purple", dash = 'dot')) %>%
layout(
title=paste0("Subject #", p),
xaxis=list(title="Time [s]", range=c(0)),
yaxis=y1,
yaxis2=y2,
margin = list(l = 50, r = 50, b = 50, t = 50, pad = 4),
legend = list(x = 0.5, xanchor = "center", y = 0.2, bgcolor = "rgba(0,0,0,0)", title="Metric", orientation = "h"),
autosize = F
)
plt_AllAcc[[p]] <- plot_Acc
}
htmltools::tagList(plt_AllAcc)
NUMBER_OF_CLUSTERS = 3
color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
dfPP <- as.data.frame(cbind(
unlist(mean_pp),
unlist(std_pp),
unlist(mean_pp_seg0),
unlist(mean_pp_seg1),
unlist(mean_pp_seg2),
unlist(mean_pp_seg3),
unlist(mean_pp_seg4),
unlist(mean_pp_max),
unlist(std_pp_seg0),
unlist(std_pp_seg1),
unlist(std_pp_seg2),
unlist(std_pp_seg3),
unlist(std_pp_seg4),
unlist(std_pp_max),
unlist(mean_pp_seg0_1),
unlist(mean_pp_seg0_2),
unlist(mean_pp_seg0_3),
unlist(mean_pp_seg0_4),
unlist(std_pp_seg0_1),
unlist(std_pp_seg0_2),
unlist(std_pp_seg0_3),
unlist(std_pp_seg0_4),
unlist(mean_pp_HighAcc),
unlist(mean_pp_LowAcc),
unlist(std_pp_HighAcc),
unlist(std_pp_LowAcc),
unlist(mean_pp_HighAcc1),
unlist(mean_pp_LowAcc1),
unlist(std_pp_HighAcc1),
unlist(std_pp_LowAcc1),
unlist(mean_pp_HighAcc2),
unlist(mean_pp_LowAcc2),
unlist(std_pp_HighAcc2),
unlist(std_pp_LowAcc2),
unlist(mean_pp_HighAcc3),
unlist(mean_pp_LowAcc3),
unlist(std_pp_HighAcc3),
unlist(std_pp_LowAcc3),
unlist(mean_pp_HighAcc4),
unlist(mean_pp_LowAcc4),
unlist(std_pp_HighAcc4),
unlist(std_pp_LowAcc4)
))
names(dfPP) <- c("MeanPP", "StdPP",
"MeanPP_Seg0", "MeanPP_Seg1", "MeanPP_Seg2", "MeanPP_Seg3", "MeanPP_Seg4", "MeanPP_SegMax",
"StdPP_Seg0", "StdPP_Seg1", "StdPP_Seg2", "StdPP_Seg3", "StdPP_Seg4", "StdPP_SegMax",
"MeanPP_Seg0_1", "MeanPP_Seg0_2", "MeanPP_Seg0_3", "MeanPP_Seg0_4",
"StdPP_Seg0_1", "StdPP_Seg0_2", "StdPP_Seg0_3", "StdPP_Seg0_4",
"MeanPP_AccHigh", " MeanPP_AccLow", "StdPP_AccHigh", "StdPP_AccLow",
"MeanPP_AccHigh1", " MeanPP_AccLow1", "StdPP_AccHigh1", "StdPP_AccLow1",
"MeanPP_AccHigh2", " MeanPP_AccLow2", "StdPP_AccHigh2", "StdPP_AccLow2",
"MeanPP_AccHigh3", " MeanPP_AccLow3", "StdPP_AccHigh3", "StdPP_AccLow3",
"MeanPP_AccHigh4", " MeanPP_AccLow4", "StdPP_AccHigh4", "StdPP_AccLow4")
behavioralMatrixClustering <- as.matrix(dfPP)
distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust(method="average")
hc <- hresults %>%
as.dendrogram %>%
set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
# set("leaves_pch", 19) %>%
# set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%
set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)
plot(hc)
legend("topright",
title="Drive=Motoric \nHierachical Clustering",
legend = c("Group 1", "Group 2", "Group 3"),
col = c("darkred", "pink" , "blue"),
pch = c(20,20,20), bty = "n", pt.cex = 1.5, cex = 0.8 ,
text.col = "black", horiz = FALSE, inset = c(0.4, 0.1))

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNvdXJjZSgnLi4vc2V0dGluZ3Mvc2V0dGluZ3MuUicpCnNvdXJjZSgnY29tbW9uRnVuY3Rpb25zLlInKQpgYGAKCmBgYHtyfQpwZXJzb25zIDwtIFNFTEVDVEVEX1NVQkpFQ1RTCgphbGxfRHJpdmUyIDwtIHJlYWQuY3N2KCcuLi8vZGF0YS9wcm9jZXNzZWQvZGlzdGFuY2V3aXNlL1RUMV9Ecml2ZV8zXzE1bV8xNW0uY3N2JykKYWxsX0RyaXZlMyA8LSByZWFkLmNzdignLi4vL2RhdGEvcHJvY2Vzc2VkL2Rpc3RhbmNld2lzZS9UVDFfRHJpdmVfM18xNW1fMTVtLmNzdicpCmFsbF9Ecml2ZTMkU3ViamVjdCA8LSBhcy5mYWN0b3IoYWxsX0RyaXZlMyRTdWJqZWN0KQphbGxfRHJpdmUzJGxvZ1BlcnNwaXJhdGlvbiA8LSBsb2coYWxsX0RyaXZlMyRQZXJzcGlyYXRpb24pCmBgYAoKIyBBY2NlbGVyYXRpb24gUGxvdApgYGB7cn0KY29tcHV0ZVRocmVzaG9sZCA8LSBmdW5jdGlvbih4LCB4bWluPW1pbih4KSwgeG1heD1tYXgoeCkpIHsKICB4IDwtIHhbeCA+PSB4bWluICYgeCA8PSB4bWF4XQogIHhBcnIgPC0gbWF0cml4KHgsIG5yb3cgPSAxLCBuY29sID0gbGVuZ3RoKHgpKQogIHRocmVzaG9sZCA8LSBvdHN1KHhBcnIsIHJhbmdlPWMoeG1pbiwgeG1heCkpCiAgcmV0dXJuKHRocmVzaG9sZCkKfQpjb21wdXRlVGhyZXNob2xkRm9yQWNjZWxlcmF0aW9uIDwtIGZ1bmN0aW9uKGFjYyl7CiAgcmV0dXJuKGNvbXB1dGVUaHJlc2hvbGQoYWNjLCB4bWluPTAsIHhtYXg9MjApKQp9CmZpbmRNb2RlcyA8LSBmdW5jdGlvbih4KSB7CiAgdXggPC0gdW5pcXVlKHgpCiAgdXhbd2hpY2gubWF4KHRhYnVsYXRlKG1hdGNoKHgsIHV4KSkpXQp9CmBgYAoKYGBge3J9CmFjY190aHJlc2hvbGRzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKGFjY190aHJlc2hvbGRzKSA8LSBwZXJzb25zCgphY2Nfc2RfdGhyZXNob2xkcyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhhY2Nfc2RfdGhyZXNob2xkcykgPC0gcGVyc29ucwoKc3BlZWRfc2RfdGhyZXNob2xkcyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzcGVlZF9zZF90aHJlc2hvbGRzKSA8LSBwZXJzb25zCgpmb3IgKHAgaW4gcGVyc29ucykgewogIHBEYXRhIDwtIGFsbF9Ecml2ZTJbKGFsbF9Ecml2ZTIkU3ViamVjdD09YXMuaW50ZWdlcihwKSB8IGFsbF9Ecml2ZTIkU3ViamVjdD09cCksXQogIGFjY190aCA8LSBjb21wdXRlVGhyZXNob2xkRm9yQWNjZWxlcmF0aW9uKHBEYXRhJEFjY2VsZXJhdGlvbikKICBhY2NfdGhfc2QgPC0gY29tcHV0ZVRocmVzaG9sZEZvckFjY2VsZXJhdGlvbihwRGF0YSRBY2Nfc3RkKQogIHNwZWVkX3RoX3NkIDwtIGNvbXB1dGVUaHJlc2hvbGRGb3JBY2NlbGVyYXRpb24ocERhdGEkU3BlZWRfc3RkKQogIGFjY190aHJlc2hvbGRzW1twXV0gPC0gYXMubnVtZXJpYyhhY2NfdGgpCiAgYWNjX3NkX3RocmVzaG9sZHNbW3BdXSA8LSBhcy5udW1lcmljKGFjY190aF9zZCkKICBzcGVlZF9zZF90aHJlc2hvbGRzW1twXV0gPC0gYXMubnVtZXJpYyhzcGVlZF90aF9zZCkKICAKICBhY2NfcGwgPC0gZ2dwbG90KHBEYXRhLCBhZXMoeD1BY2NlbGVyYXRpb24pKSArIGdlb21fZGVuc2l0eSgpICsgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1hY2NfdGgpLCBjb2xvcj0iYmx1ZSIsIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpCiAgYWNjX3NkX3BsIDwtIGdncGxvdChwRGF0YSwgYWVzKHg9QWNjX3N0ZCkpICsgZ2VvbV9kZW5zaXR5KCkgKyBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PWFjY190aF9zZCksIGNvbG9yPSJyZWQiLCBsaW5ldHlwZT0iZGFzaGVkIiwgc2l6ZT0xKQogIHNwZWVkX3NkX3BsIDwtIGdncGxvdChwRGF0YSwgYWVzKHg9U3BlZWRfc3RkKSkgKyBnZW9tX2RlbnNpdHkoKSArIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9c3BlZWRfdGhfc2QpLCBjb2xvcj0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkKICAKICBwbG90KHNwZWVkX3NkX3BsKQogIHByaW50KHBhc3RlMChwLCAiIC0gVGhyZXNob2xkIChBY2MpID0iLCBhY2NfdGgsICIgJiAoQWNjIFNEKSA9IiwgYWNjX3RoX3NkLCAiICYgKFNwZWVkIFNEKSA9IiwgYWNjX3RoX3NkKSkKICAKfQpgYGAKCmBgYHtyfQptZWFuX3BwIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHApIDwtIHBlcnNvbnMKCnN0ZF9wcCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHApIDwtIHBlcnNvbnMKCiMgTWVhbiAoVHVybmluZykKbWVhbl9wcF9zZWcwIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMCkgPC0gcGVyc29ucwptZWFuX3BwX3NlZzBfMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzBfMSkgPC0gcGVyc29ucwptZWFuX3BwX3NlZzBfMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzBfMikgPC0gcGVyc29ucwptZWFuX3BwX3NlZzBfMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzBfMykgPC0gcGVyc29ucwptZWFuX3BwX3NlZzBfNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzBfNCkgPC0gcGVyc29ucwoKIyBNZWFuIChTdHJhaWdodCkKbWVhbl9wcF9zZWcxIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMSkgPC0gcGVyc29ucwptZWFuX3BwX3NlZzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcyKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzMpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWc0IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnNCkgPC0gcGVyc29ucwptZWFuX3BwX21heCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX21heCkgPC0gcGVyc29ucwoKIyBTRCAoVHVybmluZykKc3RkX3BwX3NlZzAgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzApIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzBfMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMF8xKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWcwXzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzBfMikgPC0gcGVyc29ucwpzdGRfcHBfc2VnMF8zIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwXzMpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzBfNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMF80KSA8LSBwZXJzb25zCgojIFNEIChTdHJhaWdodCkKc3RkX3BwX3NlZzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzEpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzIpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzMpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzQpIDwtIHBlcnNvbnMKc3RkX3BwX21heCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfbWF4KSA8LSBwZXJzb25zCgojIEFjY2VsZXJhdGlvbiBQYXJ0aXRpb25pbmcKbWVhbl9wcF9IaWdoQWNjIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfSGlnaEFjYykgPC0gcGVyc29ucwptZWFuX3BwX0xvd0FjYyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0xvd0FjYykgPC0gcGVyc29ucwoKc3RkX3BwX0hpZ2hBY2MgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0hpZ2hBY2MpIDwtIHBlcnNvbnMKc3RkX3BwX0xvd0FjYyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfTG93QWNjKSA8LSBwZXJzb25zCgojIEFjY2VsICsgU2VnbWVudGF0aW9uCm1lYW5fcHBfSGlnaEFjYzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9IaWdoQWNjMSkgPC0gcGVyc29ucwptZWFuX3BwX0xvd0FjYzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9Mb3dBY2MxKSA8LSBwZXJzb25zCnN0ZF9wcF9IaWdoQWNjMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfSGlnaEFjYzEpIDwtIHBlcnNvbnMKc3RkX3BwX0xvd0FjYzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0xvd0FjYzEpIDwtIHBlcnNvbnMKCm1lYW5fcHBfSGlnaEFjYzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9IaWdoQWNjMikgPC0gcGVyc29ucwptZWFuX3BwX0xvd0FjYzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9Mb3dBY2MyKSA8LSBwZXJzb25zCnN0ZF9wcF9IaWdoQWNjMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfSGlnaEFjYzIpIDwtIHBlcnNvbnMKc3RkX3BwX0xvd0FjYzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0xvd0FjYzIpIDwtIHBlcnNvbnMKCm1lYW5fcHBfSGlnaEFjYzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9IaWdoQWNjMykgPC0gcGVyc29ucwptZWFuX3BwX0xvd0FjYzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9Mb3dBY2MzKSA8LSBwZXJzb25zCnN0ZF9wcF9IaWdoQWNjMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfSGlnaEFjYzMpIDwtIHBlcnNvbnMKc3RkX3BwX0xvd0FjYzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0xvd0FjYzMpIDwtIHBlcnNvbnMKCm1lYW5fcHBfSGlnaEFjYzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9IaWdoQWNjNCkgPC0gcGVyc29ucwptZWFuX3BwX0xvd0FjYzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9Mb3dBY2M0KSA8LSBwZXJzb25zCnN0ZF9wcF9IaWdoQWNjNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfSGlnaEFjYzQpIDwtIHBlcnNvbnMKc3RkX3BwX0xvd0FjYzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0xvd0FjYzQpIDwtIHBlcnNvbnMKCmZvcihwIGluIHBlcnNvbnMpIHsKICBwRGF0YSA8LSBhbGxfRHJpdmUzWyhhbGxfRHJpdmUzJFN1YmplY3Q9PWFzLmludGVnZXIocCkgfCBhbGxfRHJpdmUzJFN1YmplY3Q9PXApLF0KICBwRGF0YV9hY3QzIDwtIHBEYXRhW3BEYXRhJEFjdGl2aXR5PT0zLF0KICAKICAjIERhdGEgUGFydGl0aW9uaW5nCiAgcERhdGFfc2VnMCA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MCxdCiAgcERhdGFfc2VnMF8xIDwtIHBEYXRhW3BEYXRhJEFjdGl2aXR5PT0wICYgcERhdGEkUGhhc2U9PTAgJiBwRGF0YSRUaW1lID4gMTAwICYgcERhdGEkVGltZSA8IDIwMCxdCiAgcERhdGFfc2VnMF8yIDwtIHBEYXRhW3BEYXRhJEFjdGl2aXR5PT0wICYgcERhdGEkUGhhc2U9PTAgJiBwRGF0YSRUaW1lID4gMjAwICYgcERhdGEkVGltZSA8IDMwMCxdCiAgcERhdGFfc2VnMF8zIDwtIHBEYXRhW3BEYXRhJEFjdGl2aXR5PT0wICYgcERhdGEkUGhhc2U9PTAgJiBwRGF0YSRUaW1lID4gMzAwICYgcERhdGEkVGltZSA8IDQwMCxdCiAgcERhdGFfc2VnMF80IDwtIHBEYXRhW3BEYXRhJEFjdGl2aXR5PT0wICYgcERhdGEkUGhhc2U9PTAgJiBwRGF0YSRUaW1lID4gNDAwICYgcERhdGEkVGltZSA8IDUwMCxdCiAgCiAgcERhdGFfc2VnMSA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MSAmIHBEYXRhJEFjdGl2aXR5PT0zICYgcERhdGEkVGltZSA8IDExMCxdCiAgcERhdGFfc2VnMiA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MiAmIHBEYXRhJEFjdGl2aXR5PT0zICYgcERhdGEkVGltZSA8IDI1MCxdCiAgcERhdGFfc2VnMyA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MyAmIHBEYXRhJEFjdGl2aXR5PT0zICYgcERhdGEkVGltZSA8IDM1MCxdCiAgcERhdGFfc2VnNCA8LSBwRGF0YVtwRGF0YSRQaGFzZT09NCAmIHBEYXRhJEFjdGl2aXR5PT0zLF0KICAKICAjIHBEYXRhX0hpZ2hBY2MgPC0gcERhdGFbcERhdGEkQWNjZWxlcmF0aW9uID49IGFjY190aHJlc2hvbGRzW1twXV0sXQogICMgcERhdGFfTG93QWNjIDwtIHBEYXRhW3BEYXRhJEFjY2VsZXJhdGlvbiA8IGFjY190aHJlc2hvbGRzW1twXV0sXQogIHBEYXRhX0hpZ2hBY2MgPC0gcERhdGFbcERhdGEkQWNjX3N0ZCA+PSBhY2Nfc2RfdGhyZXNob2xkc1tbcF1dIHwgcERhdGEkU3BlZWRfc3RkID49IHNwZWVkX3NkX3RocmVzaG9sZHNbW3BdXSxdCiAgcERhdGFfTG93QWNjIDwtIHBEYXRhW3BEYXRhJEFjY19zdGQgPCBhY2Nfc2RfdGhyZXNob2xkc1tbcF1dICYgcERhdGEkU3BlZWRfc3RkIDwgc3BlZWRfc2RfdGhyZXNob2xkc1tbcF1dLF0KICAKICBwRGF0YV9IaWdoQWNjMSA8LSBwRGF0YV9IaWdoQWNjWyhwRGF0YV9IaWdoQWNjJERpc3RhbmNlIDwgMzUwKSxdCiAgcERhdGFfTG93QWNjMSA8LSBwRGF0YV9Mb3dBY2NbKHBEYXRhX0xvd0FjYyREaXN0YW5jZSA8IDM1MCksXQogIHBEYXRhX0hpZ2hBY2MyIDwtIHBEYXRhX0hpZ2hBY2NbKHBEYXRhX0hpZ2hBY2MkRGlzdGFuY2UgPj0gMzUwICYgcERhdGFfSGlnaEFjYyREaXN0YW5jZSA8IDcwMCksXQogIHBEYXRhX0xvd0FjYzIgPC0gcERhdGFfTG93QWNjWyhwRGF0YV9Mb3dBY2MkRGlzdGFuY2UgPj0gMzUwICYgcERhdGFfTG93QWNjJERpc3RhbmNlIDwgNzAwKSxdCiAgcERhdGFfSGlnaEFjYzMgPC0gcERhdGFfSGlnaEFjY1socERhdGFfSGlnaEFjYyREaXN0YW5jZSA+PSA3MDAgJiBwRGF0YV9IaWdoQWNjJERpc3RhbmNlIDwgMTA1MCksXQogIHBEYXRhX0xvd0FjYzMgPC0gcERhdGFfTG93QWNjWyhwRGF0YV9Mb3dBY2MkRGlzdGFuY2UgPj0gNzAwICYgcERhdGFfTG93QWNjJERpc3RhbmNlIDwgMTA1MCksXQogIHBEYXRhX0hpZ2hBY2M0IDwtIHBEYXRhX0hpZ2hBY2NbKHBEYXRhX0hpZ2hBY2MkRGlzdGFuY2UgPj0gMTA1MCksXQogIHBEYXRhX0xvd0FjYzQgPC0gcERhdGFfTG93QWNjWyhwRGF0YV9Mb3dBY2MkRGlzdGFuY2UgPj0gMTA1MCksXQogIAogIG1lYW5fcHBbW3BdXSA8LSBtZWFuKHBEYXRhX2FjdDMkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcFtbcF1dIDwtIHNkKHBEYXRhJHBwTG9nTm9ybWFsaXplZCkKICAKICBtZWFuX3BwX3NlZzBbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzAkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF8xW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzEkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF8yW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzIkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF8zW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzMkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF80W1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzQkcHBMb2dOb3JtYWxpemVkKQogIAogIG1lYW5fcHBfc2VnMVtbcF1dIDwtIG1lYW4ocERhdGFfc2VnMSRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWcyW1twXV0gPC0gbWVhbihwRGF0YV9zZWcyJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzNbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzMkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnNFtbcF1dIDwtIG1lYW4ocERhdGFfc2VnNCRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9tYXhbW3BdXSA8LSBtYXgobWVhbl9wcF9zZWcxW1twXV0sIG1lYW5fcHBfc2VnMltbcF1dLCBtZWFuX3BwX3NlZzNbW3BdXSwgbWVhbl9wcF9zZWc0W1twXV0pCiAgCiAgc3RkX3BwX3NlZzBbW3BdXSA8LSBzZChwRGF0YV9zZWcwJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF8xW1twXV0gPC0gc2QocERhdGFfc2VnMF8xJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF8yW1twXV0gPC0gc2QocERhdGFfc2VnMF8yJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF8zW1twXV0gPC0gc2QocERhdGFfc2VnMF8zJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF80W1twXV0gPC0gc2QocERhdGFfc2VnMF80JHBwTG9nTm9ybWFsaXplZCkKICAKICBzdGRfcHBfc2VnMVtbcF1dIDwtIHNkKHBEYXRhX3NlZzEkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWcyW1twXV0gPC0gc2QocERhdGFfc2VnMiRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzNbW3BdXSA8LSBzZChwRGF0YV9zZWczJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnNFtbcF1dIDwtIHNkKHBEYXRhX3NlZzQkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9tYXhbW3BdXSA8LSBtYXgoc3RkX3BwX3NlZzFbW3BdXSwgc3RkX3BwX3NlZzJbW3BdXSwgc3RkX3BwX3NlZzNbW3BdXSwgc3RkX3BwX3NlZzRbW3BdXSkKICAKICAjIEFjY2VsZXJhdGlvbgogIG1lYW5fcHBfSGlnaEFjY1tbcF1dIDwtIG1lYW4ocERhdGFfSGlnaEFjYyRwcE5leHQpCiAgbWVhbl9wcF9Mb3dBY2NbW3BdXSA8LSBtZWFuKHBEYXRhX0xvd0FjYyRwcE5leHQpCiAgc3RkX3BwX0hpZ2hBY2NbW3BdXSA8LSBzZChwRGF0YV9IaWdoQWNjJHBwTmV4dCkKICBzdGRfcHBfTG93QWNjW1twXV0gPC0gc2QocERhdGFfTG93QWNjJHBwTmV4dCkKICAKICBtZWFuX3BwX0hpZ2hBY2MxW1twXV0gPC0gbWVhbihwRGF0YV9IaWdoQWNjMSRwcE5leHQpCiAgbWVhbl9wcF9Mb3dBY2MxW1twXV0gPC0gbWVhbihwRGF0YV9Mb3dBY2MxJHBwTmV4dCkKICBzdGRfcHBfSGlnaEFjYzFbW3BdXSA8LSBzZChwRGF0YV9IaWdoQWNjMSRwcE5leHQpCiAgc3RkX3BwX0xvd0FjYzFbW3BdXSA8LSBzZChwRGF0YV9Mb3dBY2MxJHBwTmV4dCkKICAKICBtZWFuX3BwX0hpZ2hBY2MyW1twXV0gPC0gbWVhbihwRGF0YV9IaWdoQWNjMiRwcE5leHQpCiAgbWVhbl9wcF9Mb3dBY2MyW1twXV0gPC0gbWVhbihwRGF0YV9Mb3dBY2MyJHBwTmV4dCkKICBzdGRfcHBfSGlnaEFjYzJbW3BdXSA8LSBzZChwRGF0YV9IaWdoQWNjMiRwcE5leHQpCiAgc3RkX3BwX0xvd0FjYzJbW3BdXSA8LSBzZChwRGF0YV9Mb3dBY2MyJHBwTmV4dCkKICAKICBtZWFuX3BwX0hpZ2hBY2MzW1twXV0gPC0gbWVhbihwRGF0YV9IaWdoQWNjMyRwcE5leHQpCiAgbWVhbl9wcF9Mb3dBY2MzW1twXV0gPC0gbWVhbihwRGF0YV9Mb3dBY2MzJHBwTmV4dCkKICBzdGRfcHBfSGlnaEFjYzNbW3BdXSA8LSBzZChwRGF0YV9IaWdoQWNjMyRwcE5leHQpCiAgc3RkX3BwX0xvd0FjYzNbW3BdXSA8LSBzZChwRGF0YV9Mb3dBY2MzJHBwTmV4dCkKICAKICBtZWFuX3BwX0hpZ2hBY2M0W1twXV0gPC0gbWVhbihwRGF0YV9IaWdoQWNjNCRwcE5leHQpCiAgbWVhbl9wcF9Mb3dBY2M0W1twXV0gPC0gbWVhbihwRGF0YV9Mb3dBY2M0JHBwTmV4dCkKICBzdGRfcHBfSGlnaEFjYzRbW3BdXSA8LSBzZChwRGF0YV9IaWdoQWNjNCRwcE5leHQpCiAgc3RkX3BwX0xvd0FjYzRbW3BdXSA8LSBzZChwRGF0YV9Mb3dBY2M0JHBwTmV4dCkKfQoKYGBgCgpgYGB7cn0KcGx0X0FsbEFjYyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhwbHRfQWxsQWNjKSA8LSBwZXJzb25zCgpDT0xPUl9BQ0MgPSAiIzAyQTNDOCIKQ09MT1JfUFAgPSAiI0YyOEU4RSIKQ09MT1JfQlJBS0UgPSAiIzg4ODg4OCIKCnkxIDwtIGxpc3QoCiAgdGlja2ZvbnQgPSBsaXN0KGNvbG9yID0gQ09MT1JfQUNDKSwKICB0aXRsZT0iRGVncmVlIiwKICByYW5nZT1jKDAsIG1heChhbGxfRHJpdmUzJEFjY2VsZXJhdGlvbikpCikKeTIgPC0gbGlzdCgKICB0aWNrZm9udCA9IGxpc3QoY29sb3IgPSBDT0xPUl9QUCksCiAgb3ZlcmxheWluZyA9ICJ5IiwKICBzaWRlID0gInJpZ2h0IiwKICB0aXRsZSA9ICJMb2cgUGVyc3BpcmF0aW9uIiwKICBzaG93Z3JpZCA9IEZBTFNFLAogIHJhbmdlPWMoLTAuNiwgMC45KQogICMgcmFuZ2U9YyhtaW4oYWxsX0RyaXZlMyRwcExvZ05vcm1hbGl6ZWQpLCBtYXgoYWxsX0RyaXZlMyRwcExvZ05vcm1hbGl6ZWQpKQopCgpmb3IgKHAgaW4gcGVyc29ucykgewogIHBEYXRhIDwtIGFsbF9Ecml2ZTNbKGFsbF9Ecml2ZTMkU3ViamVjdD09YXMuaW50ZWdlcihwKSB8IGFsbF9Ecml2ZTMkU3ViamVjdD09cCksXQogIHBEYXRhX3NlZzAgPC0gcERhdGFbcERhdGEkUGhhc2U9PTAsXQogIHBEYXRhX3NlZzEgPC0gcERhdGFbcERhdGEkUGhhc2U9PTEgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAxMTAsXQogIHBEYXRhX3NlZzIgPC0gcERhdGFbcERhdGEkUGhhc2U9PTIgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAyNTAsXQogIHBEYXRhX3NlZzMgPC0gcERhdGFbcERhdGEkUGhhc2U9PTMgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAzNTAsXQogIHBEYXRhX3NlZzQgPC0gcERhdGFbcERhdGEkUGhhc2U9PTQgJiBwRGF0YSRBY3Rpdml0eT09MyxdCiAgCiAgcGxvdF9BY2MgPC0gcGxvdF9seShwRGF0YSwgeCA9IH5UaW1lLCBoZWlnaHQ9NDAwLCB3aWR0aD05MDApICU+JQogICAgIyBhZGRfdHJhY2UobmFtZT0iQWNjZWxlcmF0aW9uIiwgeSA9IH5BY2NlbGVyYXRpb24sIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLCBsaW5lPWxpc3Qod2lkdGg9MS41LCBjb2xvcj1DT0xPUl9BQ0MpKSAlPiUgCiAgICBhZGRfdHJhY2UobmFtZT0iUFAiLCB5ID0gfnBwTG9nTm9ybWFsaXplZCwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsIGxpbmU9bGlzdCh3aWR0aD0xLjUsIGNvbG9yPUNPTE9SX1BQKSwgeWF4aXMgPSAieTIiKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhJFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhJFRpbWUpLCB5ID0gbWVhbl9wcFtbcF1dLCB5ZW5kID0gbWVhbl9wcFtbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQIChzdHJhaWdodCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImRhcmtncmF5IiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YSRUaW1lKSwgeGVuZCA9IG1heChwRGF0YSRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnMFtbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWcwW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKHR1cm5pbmcpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJibGFjayIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGFfc2VnMSRUaW1lKSwgeGVuZCA9IG1heChwRGF0YV9zZWcxJFRpbWUpLCB5ID0gbWVhbl9wcF9zZWcxW1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzFbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoMXN0IHBhcnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhX3NlZzIkVGltZSksIHhlbmQgPSBtYXgocERhdGFfc2VnMiRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnMltbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWcyW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKDJuZCBwYXJ0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iZ3JlZW4iLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhX3NlZzMkVGltZSksIHhlbmQgPSBtYXgocERhdGFfc2VnMyRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnM1tbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWczW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKDNyZCBwYXJ0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGFfc2VnNCRUaW1lKSwgeGVuZCA9IG1heChwRGF0YV9zZWc0JFRpbWUpLCB5ID0gbWVhbl9wcF9zZWc0W1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzRbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoNHRoIHBhcnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJwdXJwbGUiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGxheW91dCgKICAgICAgdGl0bGU9cGFzdGUwKCJTdWJqZWN0ICMiLCBwKSwgCiAgICAgIHhheGlzPWxpc3QodGl0bGU9IlRpbWUgW3NdIiwgcmFuZ2U9YygwKSksIAogICAgICB5YXhpcz15MSwgCiAgICAgIHlheGlzMj15MiwgCiAgICAgIG1hcmdpbiA9IGxpc3QobCA9IDUwLCByID0gNTAsIGIgPSA1MCwgdCA9IDUwLCBwYWQgPSA0KSwKICAgICAgbGVnZW5kID0gbGlzdCh4ID0gMC41LCB4YW5jaG9yID0gImNlbnRlciIsIHkgPSAwLjIsIGJnY29sb3IgPSAicmdiYSgwLDAsMCwwKSIsIHRpdGxlPSJNZXRyaWMiLCBvcmllbnRhdGlvbiA9ICJoIiksCiAgICAgIGF1dG9zaXplID0gRgogICAgKQogIAogIHBsdF9BbGxBY2NbW3BdXSA8LSBwbG90X0FjYwp9CgoKaHRtbHRvb2xzOjp0YWdMaXN0KHBsdF9BbGxBY2MpCmBgYAoKCmBgYHtyfQpOVU1CRVJfT0ZfQ0xVU1RFUlMgPSAzCgpjb2xvcl9kYXJrcGluayA9ICIjZTc1NDgwIgpDTFVTVEVSX0JSQU5DSF9DT0xPUlMgPC0gYygiYmx1ZSIsICJkYXJrcmVkIiwgY29sb3JfZGFya3BpbmssICJibGFjayIpWzE6TlVNQkVSX09GX0NMVVNURVJTXQpDTFVTVEVSX0xBQkVMX0NPTE9SUyA8LSBjKCJibHVlIiwgImRhcmtyZWQiLCBjb2xvcl9kYXJrcGluaywgImJsYWNrIilbMTpOVU1CRVJfT0ZfQ0xVU1RFUlNdCgpkZlBQIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9tYXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWczKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9tYXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMF8xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzBfMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcwXzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMF80KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF8xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF8yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF8zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF80KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0hpZ2hBY2MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfTG93QWNjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfSGlnaEFjYyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0xvd0FjYyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9IaWdoQWNjMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9Mb3dBY2MxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfSGlnaEFjYzEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9Mb3dBY2MxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0hpZ2hBY2MyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0xvd0FjYzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9IaWdoQWNjMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0xvd0FjYzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfSGlnaEFjYzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfTG93QWNjMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0hpZ2hBY2MzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfTG93QWNjMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9IaWdoQWNjNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9Mb3dBY2M0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfSGlnaEFjYzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9Mb3dBY2M0KQogICAgICAgICAgICAgICAgICAgICkpCgpuYW1lcyhkZlBQKSA8LSBjKCJNZWFuUFAiLCAiU3RkUFAiLCAKICAgICAgICAgICAgICAgICAiTWVhblBQX1NlZzAiLCAiTWVhblBQX1NlZzEiLCAiTWVhblBQX1NlZzIiLCAiTWVhblBQX1NlZzMiLCAiTWVhblBQX1NlZzQiLCAiTWVhblBQX1NlZ01heCIsCiAgICAgICAgICAgICAgICAgIlN0ZFBQX1NlZzAiLCAiU3RkUFBfU2VnMSIsICJTdGRQUF9TZWcyIiwgIlN0ZFBQX1NlZzMiLCAiU3RkUFBfU2VnNCIsICJTdGRQUF9TZWdNYXgiLAogICAgICAgICAgICAgICAgICJNZWFuUFBfU2VnMF8xIiwgIk1lYW5QUF9TZWcwXzIiLCAiTWVhblBQX1NlZzBfMyIsICJNZWFuUFBfU2VnMF80IiwKICAgICAgICAgICAgICAgICAiU3RkUFBfU2VnMF8xIiwgIlN0ZFBQX1NlZzBfMiIsICJTdGRQUF9TZWcwXzMiLCAiU3RkUFBfU2VnMF80IiwKICAgICAgICAgICAgICAgICAiTWVhblBQX0FjY0hpZ2giLCAiIE1lYW5QUF9BY2NMb3ciLCAiU3RkUFBfQWNjSGlnaCIsICJTdGRQUF9BY2NMb3ciLAogICAgICAgICAgICAgICAgICJNZWFuUFBfQWNjSGlnaDEiLCAiIE1lYW5QUF9BY2NMb3cxIiwgIlN0ZFBQX0FjY0hpZ2gxIiwgIlN0ZFBQX0FjY0xvdzEiLAogICAgICAgICAgICAgICAgICJNZWFuUFBfQWNjSGlnaDIiLCAiIE1lYW5QUF9BY2NMb3cyIiwgIlN0ZFBQX0FjY0hpZ2gyIiwgIlN0ZFBQX0FjY0xvdzIiLAogICAgICAgICAgICAgICAgICJNZWFuUFBfQWNjSGlnaDMiLCAiIE1lYW5QUF9BY2NMb3czIiwgIlN0ZFBQX0FjY0hpZ2gzIiwgIlN0ZFBQX0FjY0xvdzMiLAogICAgICAgICAgICAgICAgICJNZWFuUFBfQWNjSGlnaDQiLCAiIE1lYW5QUF9BY2NMb3c0IiwgIlN0ZFBQX0FjY0hpZ2g0IiwgIlN0ZFBQX0FjY0xvdzQiKQoKYmVoYXZpb3JhbE1hdHJpeENsdXN0ZXJpbmcgPC0gYXMubWF0cml4KGRmUFApCgpkaXN0TWF0cml4IDwtIGRpc3QoYmVoYXZpb3JhbE1hdHJpeENsdXN0ZXJpbmcpCmhyZXN1bHRzIDwtIGRpc3RNYXRyaXggJT4lIGhjbHVzdChtZXRob2Q9ImF2ZXJhZ2UiKQoKaGMgPC0gaHJlc3VsdHMgJT4lIAogICAgICBhcy5kZW5kcm9ncmFtICU+JQogICAgICBzZXQoIm5vZGVzX2NleCIsIE5VTUJFUl9PRl9DTFVTVEVSUykgJT4lCiAgICAgIHNldCgibGFiZWxzX2NvbCIsIHZhbHVlID0gQ0xVU1RFUl9MQUJFTF9DT0xPUlMsIGs9TlVNQkVSX09GX0NMVVNURVJTKSAlPiUKICAgICAgIyBzZXQoImxlYXZlc19wY2giLCAxOSkgJT4lCiAgICAgICMgc2V0KCJsZWF2ZXNfY29sIiwgdmFsdWUgPSBjKCJncmF5IiksIGs9TlVNQkVSX09GX0NMVVNURVJTKSAlPiUgICAgCiAgICAgIHNldCgiYnJhbmNoZXNfa19jb2xvciIsIHZhbHVlPUNMVVNURVJfQlJBTkNIX0NPTE9SUywgaz1OVU1CRVJfT0ZfQ0xVU1RFUlMpCgpwbG90KGhjKQpsZWdlbmQoInRvcHJpZ2h0IiwgCiAgICAgdGl0bGU9IkRyaXZlPU1vdG9yaWMgXG5IaWVyYWNoaWNhbCBDbHVzdGVyaW5nIiwKICAgICBsZWdlbmQgPSBjKCJHcm91cCAxIiwgIkdyb3VwIDIiLCAiR3JvdXAgMyIpLCAKICAgICBjb2wgPSBjKCJkYXJrcmVkIiwgInBpbmsiICwgImJsdWUiKSwKICAgICBwY2ggPSBjKDIwLDIwLDIwKSwgYnR5ID0gIm4iLCAgcHQuY2V4ID0gMS41LCBjZXggPSAwLjggLCAKICAgICB0ZXh0LmNvbCA9ICJibGFjayIsIGhvcml6ID0gRkFMU0UsIGluc2V0ID0gYygwLjQsIDAuMSkpCmBgYAoKIyBDbHVzdGVyaW5nIHdpdGggU0Qgb2YgUFAKYGBge3J9CmxpYnJhcnkoZGVuZGV4dGVuZCkKCmNsdXN0ZXJpbmdEZiA8LSBkZlBQICU+JSBzZWxlY3QoU3RkUFApCk5VTUJFUl9PRl9DTFVTVEVSUyA9IDMKCmNvbG9yX2RhcmtwaW5rID0gIiNlNzU0ODAiCkNMVVNURVJfQlJBTkNIX0NPTE9SUyA8LSBjKCJkYXJrcmVkIiwgImJsdWUiLCAicmVkIilbMTpOVU1CRVJfT0ZfQ0xVU1RFUlNdCkNMVVNURVJfTEFCRUxfQ09MT1JTIDwtIGMoImRhcmtyZWQiLCAiYmx1ZSIsICJyZWQiKVsxOk5VTUJFUl9PRl9DTFVTVEVSU10KCmJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nIDwtIGFzLm1hdHJpeChjbHVzdGVyaW5nRGYpCnJvd25hbWVzKGJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nKSA8LSBwYXN0ZTAoIiMiLCBwZXJzb25zKQpkaXN0TWF0cml4IDwtIGRpc3QoYmVoYXZpb3JhbE1hdHJpeENsdXN0ZXJpbmcpCmhyZXN1bHRzIDwtIGRpc3RNYXRyaXggJT4lIGhjbHVzdAoKaGMgPC0gaHJlc3VsdHMgJT4lIAogICAgICBhcy5kZW5kcm9ncmFtICU+JQogICAgICBzZXQoIm5vZGVzX2NleCIsIE5VTUJFUl9PRl9DTFVTVEVSUykgJT4lCiAgICAgIHNldCgibGFiZWxzX2NvbCIsIHZhbHVlID0gQ0xVU1RFUl9MQUJFTF9DT0xPUlMsIGs9TlVNQkVSX09GX0NMVVNURVJTKSAlPiUKICAgICAgIyBzZXQoImxlYXZlc19wY2giLCAxOSkgJT4lCiAgICAgICMgc2V0KCJsZWF2ZXNfY29sIiwgdmFsdWUgPSBjKCJncmF5IiksIGs9TlVNQkVSX09GX0NMVVNURVJTKSAlPiUgICAgCiAgICAgIHNldCgiYnJhbmNoZXNfa19jb2xvciIsIHZhbHVlPUNMVVNURVJfQlJBTkNIX0NPTE9SUywgaz1OVU1CRVJfT0ZfQ0xVU1RFUlMpCgpwbG90KGhjKQpsZWdlbmQoInRvcHJpZ2h0IiwgCiAgICAgdGl0bGU9IkRyaXZlPU1vdG9yaWMgXG5DaGFuZ2Ugb2YgQXJvdXNhbCIsCiAgICAgbGVnZW5kID0gYygiRXhjZXB0aW9uYWwgU0QiICwgIkxvdyBTRCIgLCAiSGlnaCBTRCIpLCAKICAgICBjb2wgPSBjKCJkYXJrcmVkIiwgImJsdWUiICwgInJlZCIpLAogICAgIHBjaCA9IGMoMjAsMjAsMjApLCBidHkgPSAibiIsICBwdC5jZXggPSAxLjUsIGNleCA9IDAuOCAsIAogICAgIHRleHQuY29sID0gImJsYWNrIiwgaG9yaXogPSBGQUxTRSwgaW5zZXQgPSBjKDAuMCwgMC4xKSkKYGBgCgpgYGB7cn0KbGlicmFyeShjbHVzdGVyKQpzaWxob3VldHRlX3Njb3JlIDwtIGZ1bmN0aW9uKGspewogIGttIDwtIGttZWFucyhjbHVzdGVyaW5nRGYsIGNlbnRlcnMgPSBrLCBuc3RhcnQ9MjUpCiAgc3MgPC0gc2lsaG91ZXR0ZShrbSRjbHVzdGVyLCBkaXN0KGNsdXN0ZXJpbmdEZikpCiAgbWVhbihzc1ssIDNdKQp9CmsgPC0gMjoxMAphdmdfc2lsIDwtIHNhcHBseShrLCBzaWxob3VldHRlX3Njb3JlKQpwbG90KGssIHR5cGU9J2InLCBhdmdfc2lsLCB4bGFiPSdOdW1iZXIgb2YgY2x1c3RlcnMnLCB5bGFiPSdBdmVyYWdlIFNpbGhvdWV0dGUgU2NvcmVzJywgZnJhbWU9RkFMU0UpCmBgYAoKYGBge3J9CiMgU3RvcmUgY2x1c3RlcmluZyBkYXRhCmZQYXRoIDwtIHN0cl9pbnRlcnAoIi4uL2RhdGEvcHJvY2Vzc2VkL2FuYWx5c2lzL1RUMV9Ecml2ZV8zX1BQLmNzdiIpCmRmeCA8LSBkZlBQCmRmeCA8LSBjYmluZChwZXJzb25zLCBkZngpCm5hbWVzKGRmeCkgPC0gYygiU3ViamVjdCIgLCBuYW1lcyhkZlBQKSkKd3JpdGUuY3N2KGRmeCwgZlBhdGgsIHJvdy5uYW1lcyA9IEYpCmBgYAoKCg==